﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LeagueOfRila.View;
using Data;
using LeagueOfRila.Callback;
using Microsoft.Xna.Framework.Graphics;
using System.Threading;

namespace LeagueOfRila.Model
{
    public class GameModel : BaseModel
    {

        int steptimer=0;
        public List<Player> otherPlayers = new List<Player>();
        public Thread threadUpdate;
        public Map currentMap = new Map();
        public List<Texture2D> attackAnimation = new List<Texture2D>();
        public List<int> attackStep = new List<int>();
        public object lockAttack = new object();
        public bool boolAttack = true;

        public GameModel()
        {
            threadUpdate = new Thread(x => {
                int i = 0;
                int posX = Client.player.posX;
                int posY = Client.player.posY;
                float mapOriginX = this.GetView().mapOrigin.X;
                float mapOriginY = this.GetView().mapOrigin.Y;
                tellServerCharInfos();
                while (true)
                {

                    if (Client.player.posX != posX || Client.player.posY != posY || this.GetView().mapOrigin.X != mapOriginX || this.GetView().mapOrigin.Y != mapOriginY)
                    {
                        tellServerCharInfos();
                        i = 0;
                        posX = Client.player.posX;
                        posY = Client.player.posY;
                    }
                    Thread.Sleep(10);

                }
            });
        }


        public GameView GetView()
        {
            return this.view as GameView;
        }

        public void GoDown()
        {
                if (Client.player.posY > this.GetView().graphics.GraphicsDevice.Viewport.Height - 100 - Client.player.character.spriteY)
                {
                    if (currentMap.isAllowedPosition(Client.player.posX , Client.player.posY, Client.player.character.spriteX, Client.player.character.spriteY, this.GetView().map.Height, this.GetView().map.Width, this.GetView().mapOrigin.X, this.GetView().mapOrigin.Y-1))
                        this.GetView().mapOrigin.Y--;
                }
                else
                {
                    if (currentMap.isAllowedPosition(Client.player.posX, Client.player.posY+1, Client.player.character.spriteX, Client.player.character.spriteY, this.GetView().map.Height, this.GetView().map.Width, this.GetView().mapOrigin.X, this.GetView().mapOrigin.Y))
                        Client.player.posY++;
                }
              
        }
        public void GetStats()
        {
            this.GetView().DrawStats();
        }

        public void GoUp()
        {

                if (Client.player.posY < 100)
                {
                    if (currentMap.isAllowedPosition(Client.player.posX, Client.player.posY, Client.player.character.spriteX, Client.player.character.spriteY, this.GetView().map.Height, this.GetView().map.Width, this.GetView().mapOrigin.X, this.GetView().mapOrigin.Y+1))
                        this.GetView().mapOrigin.Y++;
                }
                else
                {
                    if (currentMap.isAllowedPosition(Client.player.posX, Client.player.posY - 1, Client.player.character.spriteX, Client.player.character.spriteY, this.GetView().map.Height, this.GetView().map.Width, this.GetView().mapOrigin.X, this.GetView().mapOrigin.Y))
                        Client.player.posY--;
                } 

        }

        public void GoRight()
        {
                if (Client.player.posX > this.GetView().graphics.GraphicsDevice.Viewport.Width - 150 - Client.player.character.spriteX)
                {
                    if (currentMap.isAllowedPosition(Client.player.posX, Client.player.posY, Client.player.character.spriteX, Client.player.character.spriteY, this.GetView().map.Height, this.GetView().map.Width, this.GetView().mapOrigin.X - 1, this.GetView().mapOrigin.Y))
                        this.GetView().mapOrigin.X--;
                }
                else
                {
                    if (currentMap.isAllowedPosition(Client.player.posX+1, Client.player.posY, Client.player.character.spriteX, Client.player.character.spriteY, this.GetView().map.Height, this.GetView().map.Width, this.GetView().mapOrigin.X, this.GetView().mapOrigin.Y))
                        Client.player.posX++;   
                }

        }

        public void GoLeft()
        {

                if (Client.player.posX < 150)
                {
                    if (currentMap.isAllowedPosition(Client.player.posX, Client.player.posY, Client.player.character.spriteX, Client.player.character.spriteY, this.GetView().map.Height, this.GetView().map.Width, this.GetView().mapOrigin.X+1, this.GetView().mapOrigin.Y))
                        this.GetView().mapOrigin.X++;
                    
                }
                else
                {
                    if (currentMap.isAllowedPosition(Client.player.posX - 1, Client.player.posY, Client.player.character.spriteX, Client.player.character.spriteY, this.GetView().map.Height, this.GetView().map.Width, this.GetView().mapOrigin.X, this.GetView().mapOrigin.Y))
                        Client.player.posX--;
                    
                }

        }

        public void addStep()
        {
            if (steptimer == 10)
            {
                if (Client.player.step < 3)
                {
                    Client.player.step++;
                }
                else
                {
                    Client.player.step = 0;
                }
                steptimer = 0;
            }
            steptimer++;
            
        }

        public void SetOrientation(int newO)
        {
            Client.player.orientation = newO;
        }

        public void updateCamera()
        {
            if (Client.player.posX == 150)
            {
                this.GetView().mapOrigin.X++;
            }
        }

        public void tellServerCharInfos()
        {
            //Client.cFightService.gm = this;
            CPlayerService cPlayerService = new CPlayerService();
            cPlayerService.gm = this;
            Services.GetPlayerService(cPlayerService).UpdatePlayer(Client.player.pseudo, Client.player.character.name,Client.player.posX - (int)this.GetView().mapOrigin.X  ,Client.player.posY - (int)this.GetView().mapOrigin.Y ,
                Client.player.orientation, Client.player.step, Client.player.character.life, Client.player.character.mana);
            
        }

        public void AddTexturePlayer(string pseudo, string sprite)
        {
            this.GetView().AddTexturePlayer(pseudo, sprite);
        }

        public void attackUp()
        {
                if (boolAttack && Client.player.character.life > 0)
                {
                    Thread sword = new Thread(() =>
                    {
                        if (boolAttack)
                        {
                            lock (lockAttack)
                            {

                                boolAttack = false;

                                string attackName = "sword";
                                switch (Client.player.character.name)
                                {
                                    case "Mage":
                                        attackName = "boltfire";
                                        break;
                                    case "Priest":
                                        attackName = "confession";
                                        break;
                                }
                                if (checkMana(attackName))
                                {
                                    Animation animationAttack = new Animation(attackName, Client.player, (int)this.GetView().mapOrigin.X, (int)this.GetView().mapOrigin.Y);

                                    //appel serveur
                                    CPlayerService cPlayerService = new CPlayerService();
                                    cPlayerService.gm = this;
                                    Services.GetPlayerService(cPlayerService).UpdateAnimation(Client.player.pseudo, animationAttack.posx, animationAttack.posy, animationAttack.spriteWidth, animationAttack.spriteHeight, animationAttack.type, Client.player.orientation);
                                    //animation

                                    lock (this.GetView().lockAnim)
                                    {
                                        //if (boolAttack)
                                        this.GetView().lockAnimActive = true;
                                        this.GetView().animations.Add(animationAttack);
                                        this.GetView().lockAnimActive = false;
                                    }
                                    Thread.Sleep(animationAttack.timeAnim);
                                    
                                }
                                boolAttack = true;
                                //son}  
                            }

                        }
                    });

                    sword.Start();
                }
        }

        public void attackDown()
        {
            if (boolAttack && Client.player.character.life > 0)
            {
                Thread circleFire = new Thread(() =>
                {
                    lock (lockAttack)
                    {
                        boolAttack = false;
                        string attackName = "sword";
                        switch (Client.player.character.name)
                        {
                            case "Mage":
                                attackName = "circlefire";
                                break;
                            case "War":
                                attackName = "execution";
                                break;
                            case "Matthieu":
                                attackName = "speed";
                                break;
                        }
                        if (checkMana(attackName))
                        {
                            Animation animationAttack = new Animation(attackName, Client.player, (int)this.GetView().mapOrigin.X, (int)this.GetView().mapOrigin.Y);

                            if (attackName != "speed")
                            {
                                //appel serveur
                                CPlayerService cPlayerService = new CPlayerService();
                                cPlayerService.gm = this;
                                Services.GetPlayerService(cPlayerService).UpdateAnimation(Client.player.pseudo, animationAttack.posx, animationAttack.posy, animationAttack.spriteWidth, animationAttack.spriteHeight, animationAttack.type, Client.player.orientation);
                            }
                            //animation
                            lock (this.GetView().lockAnim)
                            {
                                //if(boolAttack)
                                this.GetView().lockAnimActive = true;
                                this.GetView().animations.Add(animationAttack);
                                this.GetView().lockAnimActive = false;
                            }
                            
                            Thread.Sleep(animationAttack.timeAnim);
                            
                        }
                        boolAttack = true;
                        //son
                    }

                });
                circleFire.Start();
            }
        }

        public bool checkMana(string attackName)
        {
            int consoMana = 0;
            if(attackName == "circlefire" || attackName == "confession")
            {
                consoMana = 500;
            }
            else if (attackName == "boltfire")
            {
                consoMana = 300;
            }
            else if (attackName == "execution")
            {
                consoMana = 1000;
            }
            if (consoMana != 0)
            {
                if (Client.player.character.mana - consoMana >= 0)
                {
                    Client.player.character.mana = Client.player.character.mana - consoMana;
                    tellServerCharInfos();
                    return true;
                }
                else
                {
                    return false;
                }
            }

            return true;
        }
    }
}
